package controller

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"

	"github.com/gin-gonic/gin"
)

// HlPayTransactionCacheController HlPay交易缓存控制器
type HlPayTransactionCacheController struct {
	cacheService *service.HlPayTransactionCacheService
}

// NewHlPayTransactionCacheController 创建HlPay交易缓存控制器
func NewHlPayTransactionCacheController(cacheService *service.HlPayTransactionCacheService) *HlPayTransactionCacheController {
	return &HlPayTransactionCacheController{
		cacheService: cacheService,
	}
}

// SyncTransactions 同步交易数据
func (c *HlPayTransactionCacheController) SyncTransactions(ctx *gin.Context) {
	result, err := c.cacheService.SyncRecentTransactions(ctx)
	if err != nil {
		log.Printf("[HlPayCache] 同步交易数据失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "SYNC_TRANSACTIONS_FAILED", err)
		return
	}

	common.Success(ctx, "交易数据同步成功", result)
}

// GetUserTransactions 获取当前用户的交易记录
func (c *HlPayTransactionCacheController) GetUserTransactions(ctx *gin.Context) {
	// 从JWT token中获取当前用户ID
	userID, ok := common.RequireCurrentUserID(ctx)
	if !ok {
		return // 错误响应已在RequireCurrentUserID中处理
	}

	// 解析分页参数
	page, pageSize, err := c.parsePaginationParams(ctx)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "INVALID_PAGINATION_PARAMS", err)
		return
	}

	// 获取语言参数
	language := ctx.Query("language")

	// 获取交易类型和状态参数
	typeParam := ctx.Query("transactionType")
	statusParam := ctx.Query("status")

	// 获取卡昵称参数
	nicknameParam := ctx.Query("nickname")

	// 创建带有语言参数的上下文
	var ctxWithLang context.Context
	if language == "" {
		ctxWithLang = ctx.Request.Context()
	} else {
		ctxWithLang = context.WithValue(ctx.Request.Context(), "language", language)
	}

	log.Printf("[HlPayCache] 查询当前用户交易记录 - 用户ID: %d, 页码: %d, 页面大小: %d, 语言: %s, type: %s, status: %s", userID, page, pageSize, language, typeParam, statusParam)

	// 获取用户交易记录，增加type/status参数
	transactions, total, err := c.cacheService.GetUserTransactionsWithPagination(ctxWithLang, userID, page, pageSize, typeParam, statusParam, nicknameParam)
	if err != nil {
		log.Printf("[HlPayCache] 获取用户交易记录失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "GET_USER_TRANSACTIONS_FAILED", err)
		return
	}

	// 如果没有数据且是第一页，尝试同步
	if len(transactions) == 0 && page == 1 {
		transactions, total, err = c.trySyncAndGetTransactionsWithFilter(ctx, userID, page, pageSize, language, typeParam, statusParam, nicknameParam)
		if err != nil {
			log.Printf("[HlPayCache] 同步后获取交易记录失败: %v", err)
		}
	}

	// 构建响应
	response := c.buildPaginationResponse(transactions, total, page, pageSize)
	log.Printf("[HlPayCache] 用户 %d 交易记录查询完成，返回 %d 条记录", userID, len(transactions))

	common.Success(ctx, "获取用户交易记录成功", response)
}

// GetCardTransactions 获取卡片交易记录
func (c *HlPayTransactionCacheController) GetCardTransactions(ctx *gin.Context) {
	// 解析卡片ID
	cardID := ctx.Param("card_id")
	if cardID == "" {
		common.Error(ctx, http.StatusBadRequest, "CARD_ID_REQUIRED", fmt.Errorf("卡片ID不能为空"))
		return
	}

	// 解析分页参数
	page, pageSize, err := c.parsePaginationParams(ctx)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "INVALID_PAGINATION_PARAMS", err)
		return
	}

	// 获取语言参数
	language := ctx.Query("language")

	// 创建带有语言参数的上下文
	var ctxWithLang context.Context
	if language == "" {
		// 如果language为空，不传递语言参数，保持原始上下文
		ctxWithLang = ctx.Request.Context()
	} else {
		// 如果language不为空，传递语言参数
		ctxWithLang = context.WithValue(ctx.Request.Context(), "language", language)
	}

	log.Printf("[HlPayCache] 查询卡片交易记录 - 卡片ID: %s, 页码: %d, 页面大小: %d, 语言: %s", cardID, page, pageSize, language)

	// 获取卡片交易记录
	transactions, total, err := c.cacheService.GetCardTransactionsWithPagination(ctxWithLang, cardID, page, pageSize)
	if err != nil {
		log.Printf("[HlPayCache] 获取卡片交易记录失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "GET_CARD_TRANSACTIONS_FAILED", err)
		return
	}

	// 构建响应
	response := c.buildPaginationResponse(transactions, total, page, pageSize)
	log.Printf("[HlPayCache] 卡片 %s 交易记录查询完成，返回 %d 条记录", cardID, len(transactions))

	common.Success(ctx, "获取卡片交易记录成功", response)
}

// GetTransactionsByNickname 根据卡昵称查询交易记录
func (c *HlPayTransactionCacheController) GetTransactionsByNickname(ctx *gin.Context) {
	// 解析卡昵称
	nickname := ctx.Param("nickname")
	if nickname == "" {
		common.Error(ctx, http.StatusBadRequest, "NICKNAME_REQUIRED", fmt.Errorf("卡昵称不能为空"))
		return
	}

	// 解析分页参数
	page, pageSize, err := c.parsePaginationParams(ctx)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "INVALID_PAGINATION_PARAMS", err)
		return
	}

	log.Printf("[HlPayCache] 根据昵称查询交易记录 - 昵称: %s, 页码: %d, 页面大小: %d", nickname, page, pageSize)

	// 获取卡昵称对应的交易记录
	transactions, total, err := c.cacheService.GetTransactionsByNicknameWithPagination(ctx, nickname, page, pageSize)
	if err != nil {
		log.Printf("[HlPayCache] 获取卡昵称交易记录失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "GET_NICKNAME_TRANSACTIONS_FAILED", err)
		return
	}

	// 构建响应
	response := c.buildPaginationResponse(transactions, total, page, pageSize)
	log.Printf("[HlPayCache] 卡昵称 %s 交易记录查询完成，返回 %d 条记录", nickname, len(transactions))

	common.Success(ctx, "获取卡昵称交易记录成功", response)
}

// GetTransactionByID 根据ID获取交易记录
func (c *HlPayTransactionCacheController) GetTransactionByID(ctx *gin.Context) {
	txID := ctx.Param("transaction_id")
	if txID == "" {
		common.Error(ctx, http.StatusBadRequest, "TRANSACTION_ID_REQUIRED", fmt.Errorf("交易ID不能为空"))
		return
	}

	// 获取语言参数
	language := ctx.Query("language")

	// 创建带有语言参数的上下文
	var ctxWithLang context.Context
	if language == "" {
		ctxWithLang = ctx.Request.Context()
	} else {
		ctxWithLang = context.WithValue(ctx.Request.Context(), "language", language)
	}

	log.Printf("[HlPayCache] 查询交易记录 - 交易ID: %s, 语言: %s", txID, language)

	// 优先通过 transaction_id 查询
	transaction, err := c.cacheService.GetTransactionByID(ctxWithLang, txID)
	if err != nil {
		log.Printf("[HlPayCache] 通过 transaction_id 查询失败: %v", err)

		// 如果通过 transaction_id 没找到，尝试通过 clientTransactionId 查询
		log.Printf("[HlPayCache] 尝试通过 clientTransactionId 查询: %s", txID)
		transaction, err = c.cacheService.GetTransactionByClientTransactionID(ctxWithLang, txID)
		if err != nil {
			log.Printf("[HlPayCache] 通过 clientTransactionId 查询也失败: %v", err)
			common.Error(ctx, http.StatusNotFound, "transaction_not_found", err)
			return
		}
		log.Printf("[HlPayCache] 通过 clientTransactionId 查询成功")
	} else {
		log.Printf("[HlPayCache] 通过 transaction_id 查询成功")
	}

	common.Success(ctx, "get_transaction_record_success", transaction)
}

// GetCacheStats 获取缓存统计信息
func (c *HlPayTransactionCacheController) GetCacheStats(ctx *gin.Context) {
	stats, err := c.cacheService.GetCacheStats(ctx)
	if err != nil {
		log.Printf("[HlPayCache] 获取缓存统计信息失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "GET_CACHE_STATS_FAILED", err)
		return
	}

	common.Success(ctx, "获取缓存统计信息成功", stats)
}

// ClearCache 清理缓存
func (c *HlPayTransactionCacheController) ClearCache(ctx *gin.Context) {
	err := c.cacheService.ClearCache(ctx)
	if err != nil {
		log.Printf("[HlPayCache] 清理缓存失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "CLEAR_CACHE_FAILED", err)
		return
	}

	common.Success(ctx, "缓存清理成功", nil)
}

// UpdateConfig 更新缓存配置
func (c *HlPayTransactionCacheController) UpdateConfig(ctx *gin.Context) {
	var config service.CacheConfig
	if err := ctx.ShouldBindJSON(&config); err != nil {
		common.Error(ctx, http.StatusBadRequest, "INVALID_CONFIG_PARAMS", err)
		return
	}

	// 验证配置参数
	if err := c.validateConfig(&config); err != nil {
		common.Error(ctx, http.StatusBadRequest, "INVALID_CONFIG", err)
		return
	}

	c.cacheService.UpdateConfig(&config)
	common.Success(ctx, "缓存配置更新成功", nil)
}

// GetConfig 获取当前配置
func (c *HlPayTransactionCacheController) GetConfig(ctx *gin.Context) {
	config := c.cacheService.GetConfig()
	common.Success(ctx, "获取缓存配置成功", config)
}

// AutoSyncWithCheck 自动同步检查
func (c *HlPayTransactionCacheController) AutoSyncWithCheck(ctx *gin.Context) {
	result, err := c.cacheService.SyncRecentTransactions(ctx)
	if err != nil {
		log.Printf("[HlPayCache] 自动同步失败: %v", err)
		common.Error(ctx, http.StatusInternalServerError, "AUTO_SYNC_FAILED", err)
		return
	}

	common.Success(ctx, "自动同步完成", result)
}

// 私有方法

// parsePaginationParams 解析分页参数
func (c *HlPayTransactionCacheController) parsePaginationParams(ctx *gin.Context) (page, pageSize int, err error) {
	pageStr := ctx.DefaultQuery("pageIndex", "1")
	pageSizeStr := ctx.DefaultQuery("pageSize", "10")

	page, err = strconv.Atoi(pageStr)
	if err != nil || page <= 0 {
		page = 1
	}

	pageSize, err = strconv.Atoi(pageSizeStr)
	if err != nil || pageSize <= 0 {
		pageSize = 20
	}

	// 限制最大页面大小
	if pageSize > 100 {
		pageSize = 100
	}

	return page, pageSize, nil
}

// validateUserCards 验证用户卡片
func (c *HlPayTransactionCacheController) validateUserCards(userID int64) ([]models.UserCard, error) {
	var userCards []models.UserCard
	if err := database.DB.Where("user_id = ? AND platform = ?", userID, "hlpay").Find(&userCards).Error; err != nil {
		return nil, fmt.Errorf("查询用户卡片失败: %v", err)
	}

	log.Printf("[HlPayCache] 用户 %d 的HlPay卡片数量: %d", userID, len(userCards))
	for i, card := range userCards {
		log.Printf("[HlPayCache] 卡片 %d: ID=%s, 状态=%s, 昵称=%s",
			i+1, card.CardID, card.CardStatus, card.NikeName)
	}

	return userCards, nil
}

// trySyncAndGetTransactions 尝试同步并获取交易记录
func (c *HlPayTransactionCacheController) trySyncAndGetTransactions(ctx *gin.Context, userID int64, page, pageSize int, language string) ([]*service.HlPayCachedTransaction, int64, error) {
	log.Printf("[HlPayCache] 缓存中没有交易数据，尝试同步...")

	syncResult, err := c.cacheService.SyncRecentTransactions(ctx)
	if err != nil {
		return nil, 0, err
	}

	log.Printf("[HlPayCache] 同步完成，新增记录: %d", syncResult.NewRecords)

	var ctxWithLang context.Context
	if language == "" {
		ctxWithLang = ctx.Request.Context()
	} else {
		ctxWithLang = context.WithValue(ctx.Request.Context(), "language", language)
	}

	// 兼容老调用，补充空字符串参数
	transactions, total, err := c.cacheService.GetUserTransactionsWithPagination(ctxWithLang, userID, page, pageSize, "", "", "")
	if err != nil {
		return nil, 0, err
	}

	log.Printf("[HlPayCache] 同步后获取到 %d 条交易记录，总数: %d", len(transactions), total)
	return transactions, total, nil
}

// trySyncAndGetTransactionsWithFilter 带筛选的同步后重查
func (c *HlPayTransactionCacheController) trySyncAndGetTransactionsWithFilter(ctx *gin.Context, userID int64, page, pageSize int, language, typeParam, statusParam, nicknameParam string) ([]*service.HlPayCachedTransaction, int64, error) {
	log.Printf("[HlPayCache] 缓存中没有交易数据，尝试同步...")

	syncResult, err := c.cacheService.SyncRecentTransactions(ctx)
	if err != nil {
		return nil, 0, err
	}

	log.Printf("[HlPayCache] 同步完成，新增记录: %d", syncResult.NewRecords)

	var ctxWithLang context.Context
	if language == "" {
		ctxWithLang = ctx.Request.Context()
	} else {
		ctxWithLang = context.WithValue(ctx.Request.Context(), "language", language)
	}

	transactions, total, err := c.cacheService.GetUserTransactionsWithPagination(ctxWithLang, userID, page, pageSize, typeParam, statusParam, nicknameParam)
	if err != nil {
		return nil, 0, err
	}

	log.Printf("[HlPayCache] 同步后获取到 %d 条交易记录，总数: %d", len(transactions), total)
	return transactions, total, nil
}

// buildPaginationResponse 构建分页响应
func (c *HlPayTransactionCacheController) buildPaginationResponse(transactions []*service.HlPayCachedTransaction, total int64, page, pageSize int) map[string]interface{} {
	// 计算统计信息
	statistics := c.calculateStatistics(transactions)

	// 构建HlPay风格的分页响应
	return map[string]interface{}{
		"code":       "0000",
		"data":       transactions,
		"msg":        "success",
		"pageIndex":  page,
		"pageSize":   pageSize,
		"statistics": statistics,
		"total":      total,
	}
}

// calculateStatistics 计算交易统计信息
func (c *HlPayTransactionCacheController) calculateStatistics(transactions []*service.HlPayCachedTransaction) map[string]interface{} {
	statistics := map[string]interface{}{
		"total_transactions":  len(transactions),
		"total_amount":        0.0,
		"total_fee":           0.0,
		"by_card_form_factor": map[string]int{},
		"by_card_type":        map[string]int{},
		"by_transaction_type": map[string]int{},
	}

	for _, tx := range transactions {
		// 计算总金额
		if amount, err := strconv.ParseFloat(tx.Amount, 64); err == nil {
			statistics["total_amount"] = statistics["total_amount"].(float64) + amount
		}

		// 统计交易类型
		if tx.TransactionType != "" {
			txTypeCount := statistics["by_transaction_type"].(map[string]int)
			txTypeCount[tx.TransactionType]++
		}

		// 统计卡片类型（这里可以根据实际需求调整）
		if tx.CardId != "" {
			cardTypeCount := statistics["by_card_type"].(map[string]int)
			cardTypeCount["virtual"]++ // 假设都是虚拟卡
		}

		// 统计卡片形态（这里可以根据实际需求调整）
		cardFormCount := statistics["by_card_form_factor"].(map[string]int)
		cardFormCount["virtual"]++ // 假设都是虚拟卡
	}

	return statistics
}

// validateConfig 验证配置参数
func (c *HlPayTransactionCacheController) validateConfig(config *service.CacheConfig) error {
	if config.Expiration < 0 {
		return fmt.Errorf("缓存过期时间不能为负数")
	}
	if config.SyncInterval < 0 {
		return fmt.Errorf("同步间隔不能为负数")
	}
	if config.DaysToSync <= 0 {
		return fmt.Errorf("同步天数必须大于0")
	}
	return nil
}
